@@ -4,9 +4,10 @@ from django.conf import settings |
||
4 | 4 |
from django_logit import logit |
5 | 5 |
from django_response import response |
6 | 6 |
|
7 |
-from kodo.decorators import check_admin |
|
8 |
-from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
|
9 | 7 |
from account.models import LensmanInfo |
8 |
+from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
|
9 |
+from kodo.decorators import check_admin |
|
10 |
+ |
|
10 | 11 |
|
11 | 12 |
@logit(res=True) |
12 | 13 |
@check_admin |
@@ -21,4 +22,4 @@ def add_lensman_contribution_income_api(request, administrator): |
||
21 | 22 |
|
22 | 23 |
LensmanContributionActivityIncomeExpensesInfo.objects.update_or_create(contribution_id=contribution_id, lensman_id=lensman.lensman_id, activity_id=activity_id, user_id=user_id, defaults={'amount': amount}) |
23 | 24 |
|
24 |
- return response(200, '增加摄影师投稿收入成功') |
|
25 |
+ return response(200, '增加摄影师投稿收入成功') |
@@ -4,8 +4,8 @@ from django.conf import settings |
||
4 | 4 |
from django_logit import logit |
5 | 5 |
from django_response import response |
6 | 6 |
|
7 |
-from kodo.decorators import check_admin |
|
8 | 7 |
from apps.contract.models import LensmanContributionContractInfo |
8 |
+from kodo.decorators import check_admin |
|
9 | 9 |
|
10 | 10 |
|
11 | 11 |
@logit(res=True) |
@@ -16,7 +16,7 @@ def get_signed_contribtion_contract_file_api(request, administrator): |
||
16 | 16 |
|
17 | 17 |
contract = LensmanContributionContractInfo.objects.filter(contribution_id=contribution_id, user_id=user_id).first() |
18 | 18 |
|
19 |
- operator = { |
|
19 |
+ operator = { |
|
20 | 20 |
"UserId": settings.CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID |
21 | 21 |
} |
22 | 22 |
|
@@ -1,6 +1,7 @@ |
||
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
|
3 | 3 |
import base64 |
4 |
+import json |
|
4 | 5 |
|
5 | 6 |
import requests |
6 | 7 |
from django_logit import logit |
@@ -12,7 +13,7 @@ from apps.contract.models import LensmanContributionContractInfo |
||
12 | 13 |
from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
13 | 14 |
from member.models import MemberActivityContributionInfo |
14 | 15 |
from utils.redis.rimage import get_images_data |
15 |
-from utils.tencentcloud.ess import (create_document, create_flow, create_scheme_url, start_flow, |
|
16 |
+from utils.tencentcloud.ess import (callback_decode, create_document, create_flow, create_scheme_url, start_flow, |
|
16 | 17 |
test_upload_document_files, upload_document_files) |
17 | 18 |
|
18 | 19 |
|
@@ -181,4 +182,16 @@ def get_contribtion_contract_sign_mppath(lensman, FlowId): |
||
181 | 182 |
|
182 | 183 |
@logit(body=True, res=True) |
183 | 184 |
def ess_callback(request): |
185 |
+ # curl http://127.0.0.1:8888/api/mp/ess/callback -H 'Content-type: application/json' -X POST -d '{"encrypt":"62KE4r5Wz0yHzEpMOwVRbM1KV0"}' |
|
186 |
+ data = json.loads(request.body) |
|
187 |
+ data = callback_decode(data['encrypt']) |
|
188 |
+ MsgType = data.get('MsgType') |
|
189 |
+ if MsgType == 'FlowStatusChange': |
|
190 |
+ MsgData = data.get('MsgData', {}) |
|
191 |
+ FlowId = MsgData.get('FlowId') |
|
192 |
+ # DocumentId = MsgData.get('DocumentId') |
|
193 |
+ FlowCallbackStatus = MsgData.get('FlowCallbackStatus', -1) |
|
194 |
+ Approvers = MsgData.get('Approvers') or [{}] |
|
195 |
+ ApproveCallbackStatus = Approvers[-1].get('ApproveCallbackStatus', -1) |
|
196 |
+ LensmanContributionContractInfo.objects.filter(flow_id=FlowId).update(tencent_contract_status=FlowCallbackStatus, tencent_approve_status=ApproveCallbackStatus) |
|
184 | 197 |
return response() |
@@ -1,3 +1,13 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
1 | 3 |
from django.contrib import admin |
2 | 4 |
|
3 |
-# Register your models here. |
|
5 |
+from apps.contract.models import LensmanContributionContractInfo |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class LensmanContributionContractInfoAdmin(admin.ModelAdmin): |
|
9 |
+ list_display = ('contract_id', 'user_id', 'lensman_id', 'activity_id', 'contribution_id', 'flow_id', 'document_id', 'tencent_contract_status', 'tencent_approve_status', 'status', 'created_at', 'updated_at') |
|
10 |
+ list_filter = ('brand_id', 'coupon_expire_type', 'status') |
|
11 |
+ |
|
12 |
+ |
|
13 |
+admin.site.register(LensmanContributionContractInfo, LensmanContributionContractInfoAdmin) |
@@ -1,4 +1,5 @@ |
||
1 | 1 |
# -*- coding: utf-8 -*- |
2 |
+ |
|
2 | 3 |
from django.db import models |
3 | 4 |
from django.utils.translation import ugettext_lazy as _ |
4 | 5 |
from django_models_ext import BaseModelMixin, upload_file_path, upload_path |
@@ -8,8 +9,6 @@ from TimeConvert import TimeConvert as tc |
||
8 | 9 |
|
9 | 10 |
from utils.qiniucdn import qiniu_file_url |
10 | 11 |
|
11 |
-# Create your models here. |
|
12 |
- |
|
13 | 12 |
|
14 | 13 |
class LensmanContributionContractInfo(BaseModelMixin): |
15 | 14 |
CONTRACT_STATUS_TUPLE = ( |
@@ -67,13 +66,14 @@ class LensmanContributionContractInfo(BaseModelMixin): |
||
67 | 66 |
@property |
68 | 67 |
def contract_file_url(self): |
69 | 68 |
return qiniu_file_url(self.contract_file.name, bucket='tamron') |
70 |
- |
|
69 |
+ |
|
71 | 70 |
@property |
72 | 71 |
def contract_status(self): |
73 | 72 |
if(self.tencent_approve_status == 3 and self.tencent_contract_status == 4): |
74 | 73 |
return 1 |
75 | 74 |
else: |
76 | 75 |
return 0 |
76 |
+ |
|
77 | 77 |
@property |
78 | 78 |
def data(self): |
79 | 79 |
return { |
@@ -248,8 +248,8 @@ TENCENTCLOUD = { |
||
248 | 248 |
'template_id': '', |
249 | 249 |
'secret_id': '', |
250 | 250 |
'secret_key': '', |
251 |
- 'callback_secret_id': '', |
|
252 | 251 |
'callback_secret_key': '', |
252 |
+ 'callback_secret_token': '', |
|
253 | 253 |
'endpoint': 'ess.tencentcloudapi.com', |
254 | 254 |
'file_endpoint': 'file.ess.tencent.cn', |
255 | 255 |
}, |
@@ -9,6 +9,7 @@ mock==4.0.3 |
||
9 | 9 |
monetary==1.0.3 |
10 | 10 |
mysqlclient==2.1.1 |
11 | 11 |
pngquant==1.0.8 |
12 |
+pycryptodomex==3.20.0 |
|
12 | 13 |
pysnippets==1.1.4 |
13 | 14 |
pyzbar==0.1.9 |
14 | 15 |
qiniu==7.9.0 |
@@ -1,7 +1,9 @@ |
||
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
|
3 |
+import base64 |
|
3 | 4 |
import json |
4 | 5 |
|
6 |
+from Cryptodome.Cipher import AES |
|
5 | 7 |
from django.conf import settings |
6 | 8 |
from tencentcloud.common import credential |
7 | 9 |
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException |
@@ -16,8 +18,8 @@ operator_id = tencentcloud_cfg.get('operator_id') |
||
16 | 18 |
template_id = tencentcloud_cfg.get('template_id') |
17 | 19 |
secret_id = tencentcloud_cfg.get('secret_id') |
18 | 20 |
secret_key = tencentcloud_cfg.get('secret_key') |
19 |
-callback_secret_id = tencentcloud_cfg.get('callback_secret_id') |
|
20 | 21 |
callback_secret_key = tencentcloud_cfg.get('callback_secret_key') |
22 |
+callback_secret_token = tencentcloud_cfg.get('callback_secret_token') |
|
21 | 23 |
endpoint = tencentcloud_cfg.get('endpoint') |
22 | 24 |
file_endpoint = tencentcloud_cfg.get('file_endpoint') |
23 | 25 |
|
@@ -304,3 +306,32 @@ def create_scheme_url(flow_id=None, name=None, mobile=None, card_type='ID_CARD', |
||
304 | 306 |
resp = {} |
305 | 307 |
|
306 | 308 |
return resp |
309 |
+ |
|
310 |
+ |
|
311 |
+def decode_aes256(data, encryption_key): |
|
312 |
+ iv = encryption_key[0:16] |
|
313 |
+ aes = AES.new(encryption_key, AES.MODE_CBC, iv) |
|
314 |
+ d = aes.decrypt(data) |
|
315 |
+ unpad = lambda s: s[0:-ord(d[-1:])] |
|
316 |
+ return unpad(d) |
|
317 |
+ |
|
318 |
+ |
|
319 |
+def test_decode(): |
|
320 |
+ # https://qian.tencent.com/developers/company/callback_types_v2 |
|
321 |
+ data = "62KE4r5Wz0yHzEpMOwVRbM1KV0pPjj+cmJkT+i65MMscgfHAdNP+9K0nV/fFw1xriwi08APc/wM0mHprE43Hc91VPhRDnu2Wn0+bjzgjmy/FgZKZATR9oquy0/BCWu4C77AjkpkoU1/E7gGLr8M9u9t7zbS4AkkGK5xL5TtwI0sS+CMygmyV7bRjxebMycI52U3QJiwDRIPxFO+7yqeXYXV9AQrRskpCDBNFGW72bh+Ixw9dtX00kWcwVQ93V+mayrvdQ8oGSsL32m72kbBfahsIvIxSYSdDAEeTyokqKGfaLWD27vm55QG218IFKEsOJFDGdqCF+IBcM/+rOFeOrewvP5ehIO2KjFBecTDn0RQTlIiokXIQ4zJKvu6njePFRFoFCZjd4oiEIVn/OBw+rjXml3qwgVBQjPRtYdvDJFNENlVjlkVVmLWeS8MIdqsFWhm6Sa7O8X57mwc0cLJ22mGbyVEzNTFqeFJ/mkueW0leLcoZdjv/+IxZusqa1cpfwzkZhwi5rY6kJffNkkrxIc6OeRvpU4ECgBe/b+kxX+ObC0z9u7nzoZAOHx4akYviyIU5B1romjdfHQ/wDr5udm4Rl4NBhU/6V06Rvaadw0Ta9oBkZHGNxFWv32MnL7fVA0zVNOFDP8n+kaQiNGFAXLF4F5oIItYc5+Gp/IxfkltEki7ni7LztViE7b/ZiKSM+gzQn6fLsJ/dlUoZmh141Y0V/GPpsbxBOnWCjBZdNkLTKxdKCMScLCTysJxv7l6Swff8nAEurbzx1tvyhJAvUDnIaLyP8pRPRFq8p0xm3ZVpOo9k7A952XxVHSs40g4sr/Dihkn60aVhGtKK9DueCzn8P3cWG4TYc03M1hNlPfF+UAfnvQ1ZYAMKT/XPLqYtgRFpRkK96YfVecIrfUe9MjWl0/g4hYCAAOJurFoeGwkJiyQ8Q7DCI5EaHa3s/vI621yQyytC6D2u86RiDJxMW0PdvkUfayT7iPwC83EsfEzpQXr0yeSCQCSBgNByEuCNnZl8LAhYl05Y9+bgCzSPt6EUvmaXclYL+/EPrEmi+hzIdXUwBfhXgICT8MteJgMSgmJM2FjjGxy6uZtfHKRIzf1wk6OORPkPJtMgjlMtMs6VFC62EEeo5Xy2v1S95WT/WQ0tnGR8KjbNnmjNSRyD8VtS2mjlLXaK0xRb71YGt57O19YxQQ3R/Hq9zGqOjG+Agdl+pcvh47RlF8o3CnlU7Q==" |
|
322 |
+ encryption_key = 'TencentEssEncryptTestKey12345678' |
|
323 |
+ return callback_decode(data, encryption_key) |
|
324 |
+ |
|
325 |
+ |
|
326 |
+def callback_decode(data, encryption_key=None): |
|
327 |
+ # 此处传入密文,如果接收到的数据是{"encrypt":"base64后的密文"} |
|
328 |
+ # data = 'base64后的密文' |
|
329 |
+ data = base64.b64decode(data) |
|
330 |
+ encryption_key = encryption_key or callback_secret_key |
|
331 |
+ # encryption_key = bytes(encryption_key or callback_secret_key, encoding="utf8") |
|
332 |
+ # 此处传入CallbackUrlKey |
|
333 |
+ e = decode_aes256(data, encryption_key) |
|
334 |
+ # print(type(e)) |
|
335 |
+ # print(e) |
|
336 |
+ # print(str(e, encoding="utf8")) |
|
337 |
+ return json.loads(e) |